package cn.hamster3.mc.plugin.ball.bungee.listener;

import cn.hamster3.mc.plugin.ball.bungee.HamsterBallPlugin;
import cn.hamster3.mc.plugin.ball.common.api.BallAPI;
import cn.hamster3.mc.plugin.ball.common.entity.BallServerType;
import cn.hamster3.mc.plugin.ball.common.event.operate.*;
import cn.hamster3.mc.plugin.core.common.api.CoreAPI;
import com.google.common.eventbus.Subscribe;
import net.kyori.adventure.audience.Audience;
import net.kyori.adventure.text.serializer.bungeecord.BungeeComponentSerializer;
import net.md_5.bungee.api.ProxyServer;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.config.ServerInfo;
import net.md_5.bungee.api.connection.ProxiedPlayer;

import java.util.UUID;

public class BallBungeeListener {
    public static final BallBungeeListener INSTANCE = new BallBungeeListener();

    private BallBungeeListener() {
    }

    @Subscribe
    public void onDispatchConsoleCommand(DispatchConsoleCommandEvent event) {
        if (event.getType() != null && event.getType() != BallServerType.PROXY) {
            return;
        }
        if (event.getServerID() != null && !BallAPI.getInstance().isLocalServer(event.getServerID())) {
            return;
        }
        ProxyServer server = ProxyServer.getInstance();
        server.getPluginManager().dispatchCommand(server.getConsole(), event.getCommand());
    }

    @Subscribe
    public void onDispatchPlayerCommandEvent(DispatchPlayerCommandEvent event) {
        if (event.getType() != null && event.getType() != BallServerType.GAME) {
            return;
        }
        ProxyServer server = ProxyServer.getInstance();
        if (event.getUuid() != null) {
            ProxiedPlayer player = server.getPlayer(event.getUuid());
            if (player == null) {
                return;
            }
            server.getPluginManager().dispatchCommand(player, event.getCommand());
            return;
        }
        for (ProxiedPlayer player : server.getPlayers()) {
            server.getPluginManager().dispatchCommand(player, event.getCommand());
        }
    }

    @Subscribe
    public void onKickPlayerEvent(KickPlayerEvent event) {
        ProxiedPlayer player = ProxyServer.getInstance().getPlayer(event.getUuid());
        if (player == null) {
            return;
        }
        BaseComponent[] components = BungeeComponentSerializer.get().serialize(event.getReason());
        player.disconnect(components);
    }

    @Subscribe
    public void onSendMessageToPlayerEvent(SendMessageToPlayerEvent event) {
        for (UUID receiver : event.getReceivers()) {
            Audience audience = CoreAPI.getInstance().getAudienceProvider().player(receiver);
            event.getMessage().show(audience);
        }
    }

    @Subscribe
    public void onSendPlayerToLocationEvent(SendPlayerToLocationEvent event) {
        String serverID = event.getLocation().getServerID();
        ServerInfo toServer = ProxyServer.getInstance().getServerInfo(serverID);
        if (toServer == null) {
            HamsterBallPlugin.getInstance().getLogger().warning("试图传送玩家时失败: 服务器 " + serverID + " 不在线");
            return;
        }
        for (UUID uuid : event.getSendPlayerUUID()) {
            ProxiedPlayer player = ProxyServer.getInstance().getPlayer(uuid);
            if (player == null) {
                continue;
            }
            if (player.getServer().getInfo().getName().equals(serverID)) {
                continue;
            }
            player.connect(toServer);
        }
    }

    @Subscribe
    public void onSendPlayerToPlayer(SendPlayerToPlayerEvent event) {
        UUID toPlayerUUID = event.getToPlayerUUID();
        ProxiedPlayer toPlayer = ProxyServer.getInstance().getPlayer(toPlayerUUID);
        if (toPlayer == null) {
            HamsterBallPlugin.getInstance().getLogger().warning("试图传送玩家时失败: 目标玩家 " + toPlayerUUID + " 不在线");
            return;
        }
        ServerInfo toServer = toPlayer.getServer().getInfo();
        for (UUID uuid : event.getSendPlayerUUID()) {
            ProxiedPlayer sendPlayer = ProxyServer.getInstance().getPlayer(uuid);
            if (sendPlayer == null) {
                continue;
            }
            if (sendPlayer.getServer().getInfo().getName().equals(toServer.getName())) {
                continue;
            }
            sendPlayer.connect(toServer);
        }
    }
}
